#ifndef	_REGISTRY_H_
#define	_REGISTRY_H_

#pragma once
#ifdef WIN32
#include <atlstr.h>
#elif defined(__APPLE__)
#include "typedef_mac.h"
#include <Foundation/Foundation.h>
#elif defined(__linux__)
#include "typedef_linux.h"
#endif

#include "Regkeys.h"
#include <string>

using namespace std;
class CRegistry
{
public:
	CRegistry();
	virtual ~CRegistry();

	BOOL ClearKey();
	
	BOOL CreateKey(LPCTSTR strKey);
	BOOL DeleteKey(LPCTSTR strKey);
	BOOL DeleteValue(LPCTSTR strName);
	int GetDataSize(LPCTSTR strValueName);
	int GetSubKeyCount();

	double ReadFloat(LPCTSTR strName, double fDefault);
	int ReadInt(LPCTSTR strName, int nDefault);
	BOOL ReadBool(LPCTSTR strName, BOOL bDefault);
	DWORD ReadDword(LPCTSTR strName, DWORD dwDefault);

#ifdef WIN32
    inline BOOL PathIsValid() {	return (m_strCurrentPath.GetLength() > 0); }
    void SetLazyWrite(BOOL bSet) { m_bLazyWrite = bSet;};
	void SetWow64(BOOL bSet) { m_bUseWwow64 = bSet;}
    
    BOOL KeyExists(LPCTSTR strKey, HKEY hRootKey = NULL);
	BOOL SetKey(LPCTSTR strKey, BOOL bCanCreate);
	BOOL ValueExists(LPCTSTR strName);
    
    BOOL ReadBinary(LPCTSTR lpszEntry, LPBYTE* ppData, UINT* pBytes);
    CString ReadString(LPCTSTR strName, LPCTSTR strDefault, LPCTSTR strSubKey = _T(""));
	string ReadString1(LPCTSTR strName, LPCTSTR strDefault, LPCTSTR strSubKey = _T(""));
    
    inline CString GetCurrentPath() { return m_strCurrentPath; }
    inline HKEY GetRootKey() {return m_hRootKey; }
    BOOL SetRootKey(HKEY hRootKey);
    DWORD GetDataType(LPCTSTR strValueName, LPCTSTR strSubKey = _T(""));
    BOOL GetSubKey(int nIndex, CString &strSubKey);
	int GetValueCount(LPCTSTR strSubKey = _T(""));
	CString GetValueName(int nIndex, LPCTSTR strSubKey = _T(""));
    
    BOOL WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes);
    BOOL WriteFloat(LPCTSTR strName, double fValue);
    BOOL Write64bit(LPCTSTR strName, __int64 Value64);

#elif defined(__APPLE__)
    BOOL SetRootKey(string hRootKey);
    inline BOOL SetRootKey(NSString *hRootKey) { return SetRootKey([hRootKey UTF8String]); }
    
    BOOL KeyExists(LPCTSTR strKey);
    inline BOOL KeyExists(NSString *strKey) { return KeyExists([strKey UTF8String]); }
    inline BOOL ValueExists(NSString *strName) { return KeyExists([strName UTF8String]); }
    BOOL KeySync();
    
    NSData *ReadBinary(LPCTSTR lpszEntry);
    string ReadString(LPCTSTR strName, LPCTSTR strDefault);
    
    BOOL WriteBinary(LPCTSTR lpszEntry, NSData *pData);
    
    //
    inline double ReadFloat(NSString *strName, double fDefault) { return ReadFloat([strName UTF8String], fDefault); }
	inline int ReadInt(NSString *strName, int nDefault) { return ReadInt([strName UTF8String], nDefault); }
	inline BOOL ReadBool(NSString *strName, BOOL bDefault) { return ReadBool([strName UTF8String], bDefault); }
	inline DWORD ReadDword(NSString *strName, DWORD dwDefault) { return ReadDword([strName UTF8String], dwDefault); }
    inline NSData *ReadBinary(NSString *lpszEntry) { return ReadBinary([lpszEntry UTF8String]); }
    inline string ReadString(NSString *strName, NSString *strDefault) { return ReadString([strName UTF8String], [strDefault UTF8String]); }
    
    inline BOOL WriteBool(NSString *strName, BOOL bValue) { return WriteBool([strName UTF8String], bValue); }
	inline BOOL WriteString(NSString *strName, NSString *strValue) { return WriteString([strName UTF8String], [strValue UTF8String]); }
	inline BOOL WriteInt(NSString *strName, int nValue) { return WriteInt([strName UTF8String], nValue); }
	inline BOOL WriteDword(NSString *strName, DWORD dwValue) { return WriteDword([strName UTF8String], dwValue); }
    inline BOOL WriteBinary(NSString *lpszEntry, NSData *pData) { return WriteBinary([lpszEntry UTF8String], pData); }
#endif

	BOOL WriteBool(LPCTSTR strName, BOOL bValue);
	BOOL WriteString(LPCTSTR strName, LPCTSTR strValue);
	
	BOOL WriteInt(LPCTSTR strName, int nValue);
	BOOL WriteDword(LPCTSTR strName, DWORD dwValue);
protected:

	int m_nLastError;
#ifdef WIN32
	HKEY m_hRootKey;
    CString m_strCurrentPath;
    
	HKEY GetRootKeyEx();
	void CloseRootKeyEx(HKEY &hRootKey);
#elif defined(__APPLE__)
    NSString *m_hRootKey;
    string m_strCurrentPath;
#endif
    
	BOOL m_bLazyWrite;
	BOOL m_bUseWwow64;
	
};

#endif //_REGISTRY_H_
